iT邦幫忙

第 11 屆 iThome 鐵人賽

DAY 6
0
自我挑戰組

30 天了解 Swift 的 Combine系列 第 6

30 天了解 Swift 的 Combine: [06] More Publisher, Just, Future, Promise

  • 分享至 

  • xImage
  •  

Publisher 有許多方式可以建立, 有單獨的, 復合的, 組合的, 媒介的, 不同的 Publisher 分別有不同的型別.其中以 JustFuture 較為常見.

一般來說, Publisher 是 Value type, 每次 Subscriber 訂閱時, 都會將原本定義的 Publisher 流程重頭執行, 不論其他複製的 Publisher 是否曾經訂閱發佈過.

Just

struct Just<Output>

Just 很常被用來立即開始一個 Publisher chain, 在後面介紹 Error handling 時, 常被用來轉換 Error.

Future of Promise

final class Future<Output, Failure: Error>

要注意的是 Future.init(attemptToFulfill:) 是带入一個 Closure, 而 attemptToFulfill 的型別是:
@escaping (@escaping Future<Output, Failure>.Promise) -> Void

其中 Promise 是 Future 的 typealias

typealias Future<Output, Failure>.Promise = (Result<Output, Failure>) -> Void

為了解釋這部分, 我們需要知道 Result, (Result)->Void 分別的用途.

Result 是一個 二分法 的實作, 相似於 Optional. 在 Optional 中有一個泛型與兩個分別, 將有與無分割開來:

enum Optional<Wrapped> {
    case some(Warpped)
    case none
}

而 Result 有兩個泛型與兩個分類, 將成功與失敗分割開來:

enum Result<Success, Failure:Error> {
    case success(Success)
    case failure(Failure)
}

值得注意的是, Result.init()是可以使用 throws 函式:

Result.init(catching body: () throws -> Success)

(Result)->Void, 是一個常見的 closure 帶法, 目的可以縮減結果情形:

success failure
success V
failure V

在上表中, 我們不會發生同時成功與失敗, 也不會同時沒有成功與失敗, 因此可以更直覺的錯誤處理, 這部分可以參考 SwiftbySundell 的文章: The power of Result types in Swift

這部分沒有特別的明確中文翻譯, 筆者認定的解釋是: 延伸閉包, 用於在沒有 return 函式中執行完成後, 相依執行的部分, 使得函式可以具備延後設計的特性.


知道這兩個之後, 會更容易了解 Swift 中的 Promise, a.k.a. (Result)->Void, 而 Future 就是將 Promise 轉化成 Publisher 的復合類型:

import Combine

func mayFailure(some:Some) throws -> TYPE {
    ...
}

Futrue<TYPE, Error> { promise in 
    do {
        let type = try mayFailure(some:SOME)    
        promise(.success(type))
    }catch let error {
        promise(.failure(error))
    }
 
}

另外還有其他的 Publisher, 需要搭配情境會比較好懂:

  1. Empty
  2. Publishers.Sequence
  3. Fail
  4. Deferred
  5. ObservableObjectPublisher
  6. NotificationCenter, Timer (Foundation 延伸)
  7. @Published (在 var 之前的 property wrapper, 請參考 Property wrappers to remove boilerplate code in Swift)

簡單測驗:

  1. 嘗試理解 @Published 的運作原理
  2. 使用 Just 建立一次 Combine

上一篇
30 天了解 Swift 的 Combine: [05] Publisher與 Subscriber 的 Lifecycle + 彈珠圖
下一篇
30 天了解 Swift 的 Combine: [07] 被封裝的 Subscriber
系列文
30 天了解 Swift 的 Combine30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言